#include <buff_fifo.hpp>
#include <comm_handler.hpp>
#include <rtime.hpp>
#include <utils.hpp>
#include <udp_recver.hpp>

UdpRecver::UdpRecver(int port)
	: TaskRun(PRIORITY_UDPRECVER, 8000, "udp_recver", E_CORE_1)
	, m_DataSeqRecv(0)
	, m_DataTypeRecv(0)
	, m_SizeRecv(0)
	, rt_prev(0)
	, m_Port(port)
	, m_Socket(0)
{
	m_BuffRecv = (char*)malloc(BUFF_FIFO_SIZE);
	m_Buff	   = (char*)malloc(BUFF_FIFO_SIZE);
}

UdpRecver::~UdpRecver()
{
	free(m_BuffRecv);
	free(m_Buff);
}

void UdpRecver::Start(void* arg)
{
#if WIFI_AP_ENABLE || WIFI_STA_ENABLE
	// 创建socket
	if ((m_Socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
	{
		LOG("Udp recver socket creation failed.\n");
		return;
	}

	memset((char*)&m_ServerAddr, 0, sizeof(struct sockaddr_in));

	// 填充服务器信息
	m_ServerAddr.sin_family		 = AF_INET;
	m_ServerAddr.sin_addr.s_addr = INADDR_ANY;
	m_ServerAddr.sin_port		 = htons(m_Port);

	// 绑定socket到服务器地址
	if (bind(m_Socket, (const struct sockaddr*)&m_ServerAddr, sizeof(struct sockaddr_in)) < 0)
	{
		LOG("Udp recver bind failed.\n");
		return;
	}

	TaskRun::Start(arg);
#endif
}

void UdpRecver::Run(void* arg)
{
#if WIFI_AP_ENABLE || WIFI_STA_ENABLE
	socklen_t addLen = sizeof(struct sockaddr_in);

	struct sockaddr_in clientAddr;
	memset((char*)&clientAddr, 0, sizeof(struct sockaddr_in));

	while (1)
	{
		int rlen = recvfrom(m_Socket, m_Buff, BUFF_FIFO_SIZE, 0, (struct sockaddr*)&clientAddr, &addLen);
#if 0
		printf("Received packet from %s:%d\n",
			   inet_ntoa(clientAddr.sin_addr),
			   ntohs(clientAddr.sin_port));
#endif
		if (rlen > 0)
		{
			m_BuffFifo.Append(m_Buff, rlen);
			while (1)
			{
				if (m_Protocol.Unpack(m_BuffRecv, &m_SizeRecv, &m_DataSeqRecv, &m_DataTypeRecv, &m_BuffFifo) != 0)
				{
					break;
				}

				CommHandler* handler = CommHandler::Instance();
				handler->HandlerExec(m_DataTypeRecv, m_BuffRecv, m_SizeRecv);
			}
		}
	}
#endif
}
